package redistool

import (
	"context"
	"encoding/json"
	"errors"
	"github.com/redis/go-redis/v9"
	"local.public/innerpkg/logger"
)

var ctx = context.Background()
var rdb *redis.Client

func InitRedisCache(redisAddr string, redisDB int) error {
	lrdb, err := NewRedisCache(redisAddr, redisDB)
	if err != nil {
		return err
	}
	rdb = lrdb

	return nil
}

func NewRedisCache(redisAddr string, redisDB int) (*redis.Client, error) {

	cache := redis.NewClient(&redis.Options{
		Addr:     redisAddr,
		Password: "",      // no password set
		DB:       redisDB, // use default DB
	})
	if cache == nil {
		err := errors.New("初始化Redis连接失败！")
		return nil, err
	}
	logger.Info("已建立Redis缓存")
	return cache, nil
}

func CloseRedisCache() error {
	if rdb != nil {
		return rdb.Close()
	}
	return nil
}

// RedSet redis 设置内存数据的方法
func RedSet(key string, val string) (err error) {
	err = rdb.Set(ctx, key, val, 0).Err()
	return err
}

// RedGet redis 获取内存数据的方法
func RedGet(key string) (val string, err error) {
	val, err = rdb.Get(ctx, key).Result()
	return val, err
}

// RedDel redis 删除内存数据的方法
func RedDel(key string) (res int64, err error) {
	res, err = rdb.Del(ctx, key).Result()
	return res, err
}

func RedExists(key string) (result int64, err error) {
	result, err = rdb.Exists(ctx, key).Result()
	return result, err
}

// RedHGetAll redis 获取哈希数据
func RedHGetAll(key string) (result map[string]string, err error) {
	result, err = rdb.HGetAll(ctx, key).Result()
	return result, err
}

// RedHExists redis 判断哈希数据字段是否存在
func RedHExists(key string, field string) (result bool, err error) {
	result, err = rdb.HExists(ctx, key, field).Result()
	return result, err
}

// RedHGet redis 获取哈希数据字段
func RedHGet(key string, field string) (result string, err error) {
	result, err = rdb.HGet(ctx, key, field).Result()
	return result, err
}

// RedHSet redis 设置哈希数据字段 string int bytes
func RedHSet(key string, field string, value interface{}) (err error) {
	err = rdb.HSet(ctx, key, field, value).Err()
	return err
}

// RedHSetObj redis 设置内存数据
func RedHSetObj(key string, field string, obj interface{}) (err error) {
	bytes, err := json.Marshal(obj)
	if err != nil {
		return err
	}
	err = rdb.HSet(ctx, key, field, bytes).Err()
	return err
}

// RedHDel redis 设置内存数据的方法
func RedHDel(key string, field ...string) (result int64, err error) {
	result, err = rdb.HDel(ctx, key, field...).Result()
	return result, err
}

func RedHIncrby(key, field string) (result int64, err error) {
	result, err = rdb.HIncrBy(ctx, key, field, 1).Result()
	return
}

func RedScan(keyPrefix string) (resList []string, err error) {
	var cursor uint64
	for {
		var keys []string
		var err error
		keys, cursor, err = rdb.Scan(ctx, cursor, "*", 0).Result()
		if err != nil {
			return []string{}, err
		}

		for _, key := range keys {
			resList = append(resList, key)
		}

		// 没有更多key了
		if cursor == 0 {
			break
		}
	}
	return
}
